package com.cook.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cook.dto.recipes.StepsDTO;
import com.cook.entity.Steps;
import com.cook.service.StepsService;
import com.cook.mapper.StepsMapper;
import com.cook.vo.recipes.StepsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author black-white spider
* @description 针对表【steps(食谱步骤表)】的数据库操作Service实现
* @createDate 2025-10-27 19:55:23
*/
@Service
@Slf4j
public class StepsServiceImpl extends ServiceImpl<StepsMapper, Steps>
    implements StepsService{

    @Autowired
    private StepsMapper stepsMapper;

    /**
     * 查询食谱步骤
     * @param recipeId 食谱ID
     * @return
     */
    public List<StepsVO> getStepsByRecipeId(Long recipeId) {
        log.info("查询食谱步骤: recipeId={}", recipeId);

        try {
            List<StepsVO> steps = stepsMapper.selectByRecipeId(recipeId);
            log.info("查询到 {} 个步骤", steps.size());
            return steps;
        } catch (Exception e) {
            log.error("查询步骤列表失败: recipeId={}", recipeId, e);
            throw new RuntimeException("查询步骤失败");
        }
    }

    /**
     * 查看步骤详情
     * @param stepId 步骤ID
     * @return
     */
    public StepsVO getStepById(Long stepId) {
        log.info("查询步骤详情: stepId={}", stepId);

        try {
            StepsVO step = stepsMapper.selectByStepId(stepId);
            if (step == null) {
                log.warn("步骤不存在: step极Id={}", stepId);
                throw new RuntimeException("步骤不存在");
            }
            return step;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询步骤详情失败: stepId={}", stepId, e);
            throw new RuntimeException("极查询步骤失败");
        }
    }

    /**
     * 添加步骤
     * @param stepsDTO 步骤DTO
     * @return
     */
    @Transactional
    public Long addStep(StepsDTO stepsDTO) {
        log.info("添加步骤: recipeId={}, stepNumber={}", stepsDTO.getRecipeId(), stepsDTO.getStepNumber());

        try {
            // 如果未指定步骤序号，自动设置为最大值+1
            if (stepsDTO.getStepNumber() == null) {
                Integer maxStepNumber = stepsMapper.selectMaxStepNumber(stepsDTO.getRecipeId());
                stepsDTO.setStepNumber(maxStepNumber + 1);
            }

            Steps step = new Steps();
            BeanUtils.copyProperties(stepsDTO, step);

            int result = stepsMapper.insertStep(step);
            if (result > 0) {
                log.info("步骤添加成功: stepId={}", step.getStepId());
                return step.getStepId();
            } else {
                throw new RuntimeException("添加步骤失败");
            }
        } catch (Exception e) {
            log.error("添加步骤失败: ", e);
            throw new RuntimeException("添加步骤失败");
        }
    }

    /**
     * 批量添加步骤
     * @param stepsDTOList 步骤DTO列表
     * @return
     */
    @Transactional
    public boolean batchAddSteps(List<StepsDTO> stepsDTOList) {
        log.info("批量添加步骤: 共 {} 个", stepsDTOList.size());

        if (stepsDTOList == null || stepsDTOList.isEmpty()) {
            throw new IllegalArgumentException("步骤列表不能为空");
        }

        try {
            // DTO转Entity
            List<Steps> stepsList = stepsDTOList.stream()
                    .map(dto -> {
                        Steps step = new Steps();
                        BeanUtils.copyProperties(dto, step);
                        return step;
                    })
                    .collect(Collectors.toList());

            int result = stepsMapper.batchInsertSteps(stepsList);
            boolean success = result == stepsDTOList.size();

            if (success) {
                log.info("批量添加步骤成功: 共 {} 个", result);
            } else {
                log.warn("批量添加步骤部分失败: 成功 {} 个，总共 {} 个", result, stepsDTOList.size());
            }

            return result > 0;
        } catch (Exception e) {
            log.error("批量添加步骤失败: ", e);
            throw new RuntimeException("批量添加步骤失败");
        }
    }

    /**
     * 更新步骤
     * @param stepsDTO 步骤DTO
     * @return
     */
    @Transactional
    public boolean updateStep(StepsDTO stepsDTO) {
        log.info("更新步骤: stepId={}", stepsDTO.getStepId());

        try {
            Steps step = new Steps();
            BeanUtils.copyProperties(stepsDTO, step);

            int result = stepsMapper.updateStep(step);
            boolean success = result > 0;

            if (success) {
                log.info("步骤更新成功: stepId={}", step.getStepId());
            } else {
                log.warn("步骤更新失败: stepId={}", step.getStepId());
            }

            return success;
        } catch (Exception e) {
            log.error("更新步骤失败: ", e);
            throw new RuntimeException("更新步骤失败");
        }
    }

    /**
     * 删除步骤
     * @param stepId 步骤ID
     * @return
     */
    @Transactional
    public boolean deleteStep(Long stepId) {
        log.info("删除步骤: stepId={}", stepId);

        try {
            // 先获取步骤信息，用于后续重新排序
            StepsVO step = getStepById(stepId);

            int result = stepsMapper.deleteById(stepId);
            boolean success = result > 0;

            if (success) {
                log.info("步骤删除成功: stepId={}", stepId);
                // 删除后重新排序
                reorderSteps(step.getRecipeId());
            } else {
                log.warn("步骤删除失败: stepId={}", stepId);
            }

            return success;
        } catch (Exception e) {
            log.error("删除步骤失败: stepId={}", stepId, e);
            throw new RuntimeException("删除步骤失败");
        }
    }

    /**
     * 删除食谱所有步骤
     * @param recipeId 食谱ID
     * @return
     */
    @Transactional
    public boolean deleteStepsByRecipeId(Long recipeId) {
        log.info("删除食谱所有步骤: recipeId={}", recipeId);

        try {
            int result = stepsMapper.deleteByRecipeId(recipeId);
            boolean success = result >= 0; // 可能为0（没有步骤）

            if (success) {
                log.info("食谱步骤删除成功: recipeId={}, 删除 {} 个步骤", recipeId, result);
            } else {
                log.warn("食谱步骤删除失败: recipeId={}", recipeId);
            }

            return success;
        } catch (Exception e) {
            log.error("删除食谱步骤失败: recipe极Id={}", recipeId, e);
            throw new RuntimeException("删除步骤失败");
        }
    }

    /**
     * 重新排序步骤
     * @param recipeId 食谱ID
     * @return
     */
    @Transactional
    public boolean reorderSteps(Long recipeId) {
        log.info("重新排序步骤: recipeId={}", recipeId);

        try {
            int result = stepsMapper.reorderStepNumbers(recipeId);
            boolean success = result >= 0;

            if (success) {
                log.info("步骤重新排序成功: recipeId={}", recipeId);
            } else {
                log.warn("步骤重新排序失败: recipeId={}", recipeId);
            }

            return success;
        } catch (Exception e) {
            log.error("重新排序步骤失败: recipeId={}", recipeId, e);
            throw new RuntimeException("重新排序步骤失败");
        }
    }
}




